/*
XCommander Extension
http://www.xcommander.ch/
*/

function XCommanderMessageClient() {

}

XCommanderMessageClient.prototype = {
	_requests : [],
	_generateId : function() {
		return Math.random();
	},
	_onMessage : function(request) {
		if( typeof this._requests[request.id] == 'function') {
			this._requests[request.id](request.data);
			delete this._requests[request.id];
		}
	},
	postMessage : function(type, data, callback) {
		var id = this._generateId();
		var message = {
			'id' : id,
			'type' : type,
			'data' : data
		};
		if( typeof callback == 'function') {
			this._requests[id] = callback;
		}
		xcommander.lib.browser.postMessage(message, callback);
	}
};

/*
 * XCommanderXHR stub
 */

function XCommanderXHRStub() {

}

XCommanderXHRStub.prototype = {
	send : function(request, callback) {
		xcommander.lib.messaging.client.postMessage('xhr', request, callback);
	}
}

/*
 * XCommanderBrowser stub
 */
function XCommanderBrowserStub() {

}

XCommanderBrowserStub.createBrowser = function() {
	// check for google chrome
	if(window.chrome != undefined && window.chrome.extension != undefined) {
		XCommanderChrome.prototype = new XCommanderBrowserStub();
		return new XCommanderChrome();
	}
	// check for safari
	else if(window.safari != undefined) {
		XCommanderSafari.prototype = new XCommanderBrowserStub();
		return new XCommanderSafari();
	}//check for opera
	else if(window.opera != undefined) {
		XCommanderOpera.prototype = new XCommanderBrowserStub();
		return new XCommanderOpera();
	} else
		throw 'Unsupported Browser';

}

XCommanderBrowserStub.prototype = {

	createTab : function(url, callback) {
		xcommander.lib.messaging.client.postMessage('browser', {
			'method' : 'createTab',
			'url' : url
		}, callback);
	},
	navigateTo : function(url, callback) {
		xcommander.lib.messaging.client.postMessage('browser', {
			'method' : 'navigateTo',
			'url' : url
		}, callback);
	},
	getExtensionUrl : function(relativePath, callback) {
		xcommander.lib.messaging.client.postMessage('browser', {
			'method' : 'getExtensionUrl',
			'relativePath' : relativePath
		}, callback);
	}
}

// chrome
function XCommanderChrome() {
	this.postMessage = function(message, callback) {
		delete xcommander.lib.messaging.client._requests[message.id];
		if( typeof callback == 'function') {
			chrome.extension.sendRequest(message, callback);
		} else {
			chrome.extension.sendRequest(message);
		}
	}
}

// safari
function XCommanderSafari() {
	this.postMessage = function(message, callback) {
		safari.self.tab.dispatchMessage(message.type, {
			'id' : message.id,
			'data' : message.data
		});
	}

	safari.self.addEventListener('message', function(request) {
		xcommander.lib.messaging.client._onMessage(request.message);
	}, false);
}

// opera
function XCommanderOpera() {
	this.postMessage = function(message, callback) {
		opera.extension.postMessage(message);
	}

	opera.extension.onmessage = function(request) {
		xcommander.lib.messaging.client._onMessage(request.data);
	};
}

/*
 * XCommanderStorage stub
 */
function XCommanderStorageStub() {
}

XCommanderStorageStub.prototype = {
	getItem : function(key, callback) {
		xcommander.lib.messaging.client.postMessage('storage', {
			'method' : 'getItem',
			'key' : key
		}, callback);
	},
	getJSONItem : function(key, callback) {
		xcommander.lib.messaging.client.postMessage('storage', {
			'method' : 'getJSONItem',
			'key' : key
		}, callback);
	},
	setItem : function(key, value, callback) {
		xcommander.lib.messaging.client.postMessage('storage', {
			'method' : 'setItem',
			'key' : key,
			'value' : value
		}, callback);
	},
	setJSONItem : function(key, value, callback) {
		xcommander.lib.messaging.client.postMessage('storage', {
			'method' : 'setJSONItem',
			'key' : key,
			'value' : value
		}, callback);
	},
	removeItem : function(key, callback) {
		xcommander.lib.messaging.client.postMessage('storage', {
			'method' : 'removeItem',
			'key' : key
		}, callback);
	},
	clear : function(callback) {
		xcommander.lib.messaging.client.postMessage('storage', {
			'method' : 'clear'
		}, callback);
	},
	getKeys : function(callback) {
		xcommander.lib.messaging.client.postMessage('storage', {
			'method' : 'getKeys'
		}, callback);
	}
};

function XCommanderStub() {
	this.messaging = {};
	this.messaging.client = new XCommanderMessageClient();
	this.storage = new XCommanderStorageStub();
	this.xhr = new XCommanderXHRStub();
	this.browser = XCommanderBrowserStub.createBrowser();
}